//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using CommunityServer.Blogs.Components;
using CommunityServer.Components;

namespace CommunityServer.Components.SearchBarrel
{
	/// <summary>
	/// Summary description for WeblogSearchJob.
	/// </summary>
	public class WeblogSearchJob : SearchJob
	{
		public WeblogSearchJob()
		{
			//
			// TODO: Add constructor logic here
			//
		}


        public override void IndexPosts(int setSize, int settingsID)
        {
	                            
            WeblogDataProvider wdp = WeblogDataProvider.Instance();
            PostSet postSet =  wdp.SearchReindexPosts(setSize, settingsID);

            
            foreach (Post post in postSet.Posts) 
            {

                Hashtable words = new Hashtable();
                int totalBodyWords = 0;

                WeblogPost wp = post as WeblogPost;
                if(wp != null)
                {
                    if(wp.HasExcerpt)
                        words = Index(wp.Excerpt, words, WordLocation.Excerpt, settingsID);

                    words = Index(wp.Username, words, WordLocation.Author, settingsID);

                    // Process the post subject
                    //
                    words = Index(wp.Subject, words, WordLocation.Subject, settingsID);

                    // Process the post body
                    //
                    words = Index(wp.Body, words, WordLocation.Body, settingsID);

                    // Get a count of the total words in the body
                    //
                    totalBodyWords = SearchTerms.CleanSearchTerms(post.Body).Length;
                    InsertIntoSearchBarrel(words, post, settingsID, totalBodyWords);
                }

            }
        }

        protected override double CalculateWordRank(Word word, Post post, int totalBodyWords)
        {
            int wordOccurrence = 0;
            double replyWeight = 0;
            double wordCount = 0;
            int locked = 0;
            int pinned = 0;

            // Word weighting:
            // ============================
            // Word Occurence:      20
            // Replies:             20
            // Total words in post: 20
            // Locked:               5
            // Pinned:               5
            // Word in Excerpt:      5
            // Word in Subject:     10
            //                    ----
            // Max score:           85

            // Assign a score for how many times the word occurs in the post
            //
            wordOccurrence = word.Occurence * 2;
            if (wordOccurrence > 20)
                wordOccurrence = 20;

            // Calculate the score for replies
            //
            if ( (post.PostLevel == 1) && (post.Replies == 0)) 
            {
            
                replyWeight = 0;  // A post with no replies

            } 
            else 
            {

                replyWeight = ( (post.PostLevel - (post.Replies * 0.01)) / (post.PostLevel + post.Replies) ) * 20f;

                // If less than 0, weighting is 0
                if (replyWeight < 0)
                    replyWeight = 0;

            }

            // Calculate a score for the count of total words in the post
            //
            if (totalBodyWords > 65)
                wordCount = 20;
            else
                wordCount = (totalBodyWords / 65f) * 20f;

            // Calculate a score if the post is locked or pinned
            //
            if (post.IsLocked)
                locked = 5;
            if (post is IThread) 
            {
                if ( ((IThread) post).IsAnnouncement)
                    pinned = 5;
            }

            // Calculate the final weight of the word
            //
            return (wordOccurrence + replyWeight + word.OccurenceWeight + wordCount + locked + pinned) / 85f;
        }

	}
}
